package com.runmonk.core.study.java_8_new_features;

import java.util.Arrays;
import java.util.List;

/**
 * java8新特性
 * <p>
 * lambda表达式的demo类
 */
public class LambdaTest {
    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
        test5();

    }

    /**
     * 最简单的Lambda表达式可由逗号分隔的参数列表、->符号和语句块组成，例如：
     */
    static void test1() {
        Arrays.asList("a", "b", "d").forEach(e -> System.out.println(e));
    }

    /**
     * Lambda表达式可以引用类成员和局部变量（会将这些变量隐式得转换成final的）
     * <p>
     * test2 test3 效果一样
     */
    static void test2() {
        String separator = ",";
        Arrays.asList("a", "b", "d").forEach(
                (String e) -> System.out.print(e + separator));
    }

    static void test3() {
        final String separator = ",";
        Arrays.asList("a", "b", "d").forEach(
                (String e) -> System.out.print(e + separator));
    }

    /**
     * Lambda表达式有返回值，返回值的类型也由编译器推理得出。如果Lambda表达式中的语句块只有一行，则可以不用使用return语句
     * test4 test5 效果一样
     */
    static void test4() {
        List<String> list = Arrays.asList("c", "a", "d");
        list.sort((e1, e2) -> e1.compareTo(e2));
        list.forEach(e -> System.out.println(e));
    }

    static void test5() {
        List<String> list = Arrays.asList("c", "a", "d");
        list.sort((e1, e2) -> {
            int result = e1.compareTo(e2);
            return result;
        });
        list.forEach((String e) -> System.out.println(e));
    }

    /**
     * 函数接口指的是只有一个函数的接口，这样的接口可以隐式转换为Lambda表达式。java.lang.Runnable和java.util.concurrent.Callable是函数式接口的最佳例子。
     * 在实践中，函数式接口非常脆弱：只要某个开发者在该接口中添加一个函数，则该接口就不再是函数式接口进而导致编译失败。
     * 为了克服这种代码层面的脆弱性，并显式说明某个接口是函数式接口，
     * Java 8 提供了一个特殊的注解@FunctionalInterface（Java 库中的所有相关接口都已经带有这个注解了）
     */
    @FunctionalInterface
    private interface FunctionalDefaultMethods {
        void method();

        default void defaultMethod() {
        }
    }


}
